<?php


namespace catchAdmin\stock\controller;


use catchAdmin\stock\model\Move as MoveModel;
use catchAdmin\stock\model\Stock;
use catchAdmin\storehouse\controller\InventoryOperationRecord;
use catchAdmin\storehouse\model\Tray;
use catcher\base\CatchController;
use catcher\base\CatchRequest as Request;
use catcher\CatchAuth;
use catcher\CatchResponse;
use catcher\Utils;
use think\Exception;
use think\facade\Db;

class Move extends CatchController
{
    protected $move;

    public function __construct(MoveModel $move)
    {
        $this->move = $move;
    }

    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function index(CatchAuth $auth)
    {
        $user = $auth->user();
        return CatchResponse::paginate($this->move->getList($user['tenant_id']));
    }

    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function getStock(CatchAuth $auth,Request $request){
        $params = $request->param();
        $user = $auth->user();
        $where = [];
        if(!empty($params)){
            if(array_key_exists('config_name',$params) == true){
                $config_id = Db::table('db_warehouse_config')->where('name',$params['config_name'])->value('config_id');
                $where['s.config_id|b.config_id|sl.config_id'] = $config_id;
                unset($where['config_name']);
            }
            if(array_key_exists('goods_name',$params) == true){
                $where['s.goods_name'] = $params['goods_name'];
            }
            if(array_key_exists('tray_id',$params) == true){
                $where['s.tray_id'] = $params['tray_id'];
            }
            if(array_key_exists('createtime',$params) == true){
                $where['s.createtime'] = $params['createtime'];
            }
            if(array_key_exists('warehousing_id',$params) == true){
                $where['s.warehousing_id'] = $params['warehousing_id'];
            }
            if(!empty($params['searchForm']['goods_name'])){
                $where[]=['s.goods_name','like','%'.$params['searchForm']['goods_name'].'%'];
            }
            if(!empty($params['searchForm']['project_name'])){
                $where[]=['x.project_name','like','%'.$params['searchForm']['project_name'].'%'];
            }
            if(!empty($params['searchForm']['warehousing_id'])){
                $where[]=['s.warehousing_id','like','%'.$params['searchForm']['warehousing_id'].'%'];
            }
            if(!empty($params['searchForm']['tray_id'])){
                $where[]=['s.tray_id','like','%'.$params['searchForm']['tray_id'].'%'];
            }
        }
        $where[]=['s.tenant_id','=',$user['tenant_id']];
        $where[]=['s.deleted_at','=',0];

        $stock = Db::table('db_stock')->alias('s')
            ->join('db_warehouse_config w','w.config_id = s.config_id','LEFT')
//            ->join('db_project x','s.project_id = x.project_id','LEFT')
            ->join('db_project x','s.project_client = x.project_id','LEFT')
            ->join('db_packing p','p.packing_id = s.packing_id','LEFT')
            ->field('s.*,w.name as config_name,p.layup_num,(s.Good_Qty + s.Hold_Qty + s.NG_Qty)  as stock')
            ->where($where)
            ->having('stock > 0')
            ->order('created_at','desc')
            ->select()->toArray();


//        return json($stock);

        //捡获锁定的库存，无法操作移库
        $pick_stock_ids = Db::table('db_pick')->where([
//            ['tenant_id','=',$user['tenant_id']],
            ['deleted_at','=',0],
            ['status','=',0]
        ])->column('stock_id');


        foreach ($stock as &$value){
            if(in_array($value['stock_id'],$pick_stock_ids)){
                $value['disabled'] = true;
                $value['stock_current_status'] = '捡货锁定中';
            }else{
                $value['stock_current_status'] = '正常';
            }

            $value['_stock_num'] = array_sum([$value['Good_Qty'],$value['Hold_Qty'],$value['NG_Qty']]);

            if(empty($value['box_id']) && empty($value['slice_id'])){
                $value['_stock_type'] = 'tray';
                $value['slice_id'] = '';
                $value['box_id'] = '';
                //重新计算可以拆多少箱
                if(0 == $value['packing_num']){//不懂库存表为啥有0包装规格，先过滤了
                    unset($value);
                    continue;
                }
                $value['_split_box_number'] = ceil($value['_stock_num'] / $value['packing_num']);
            }elseif(!empty($value['box_id']) && empty($value['slice_id'])){
                $value['_stock_type'] = 'box';
                $value['slice_id'] = '';
                $value['_split_box_number'] = 1;
            }else{
                $value['_stock_type'] = 'slice';
            }
        }


//        $stock = Db::table('db_stock')->alias('s')
//            ->join('db_box b','s.tray_id = b.tray_id and b.status <> "1"','LEFT')
//            ->join('db_slice sl','b.box_id = sl.box_id and sl.status = "0"','LEFT')
//            ->join('db_warehousing_son ws','ws.warehousing_son_id = s.warehousing_son_id','LEFT')
//            ->join('db_warehousing w','w.warehousing_id = s.warehousing_id','LEFT')
//            ->field('s.id,s.tray_id,s.number,s.goods_id,s.goods_name,s.Good_Qty,s.warehousing_id,s.warehousing_son_id,s.config_id,s.created_at,s.packing_num,s.unit_name,b.box_id,b.Good_Qty as Good_Qty2,b.config_id as config_id2,sl.slice_id,sl.number as Good_Qty3,sl.config_id as config_id3,w.customer_business_number,ws.batch_number')
//            ->where($where)
//            ->select()->toArray();
//        if($stock){
//            $where1['tenant_id'] = $user['tenant_id'];
//            $where1['deleted_at'] = 0;
//            $config = Db::table('db_warehouse_config')->field('config_id,name')->where($where1)->select()->toArray();
//
//            foreach ($stock as $key => $value) {
//                if(!empty($value['tray_id']) && !empty($value['box_id']) && empty($value['slice_id'])){
//                    $stock[$key]['Good_Qty'] = $stock[$key]['Good_Qty2'];
//                    $stock[$key]['config_id'] = $stock[$key]['config_id2'];
//                }elseif(!empty($value['tray_id']) && !empty($value['box_id']) && !empty($value['slice_id'])){
//                    $stock[$key]['Good_Qty'] = $stock[$key]['Good_Qty3'];
//                    $stock[$key]['config_id'] = $stock[$key]['config_id3'];
//                }
//
//                unset($stock[$key]['Good_Qty2']);
//                unset($stock[$key]['Good_Qty3']);
//                unset($stock[$key]['config_id2']);
//                unset($stock[$key]['config_id3']);
//
//                foreach ($config as $k1 => $v1) {
//                    if($stock[$key]['config_id'] == $v1['config_id']){
//                        $stock[$key]['config_name'] = $v1['name'];
//                    }
//                }
//            }
//        }else{
//            $stock = [];
//        }


        return CatchResponse::success($stock, '查询成功');

    }
    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function create(CatchAuth $auth,Request $request)
    {
        $params = $request->param();
        $user = $auth->user();
        $params['tenant_id'] = $user['tenant_id'];
        $configs = [];
        foreach ($params['config_id_two'] as $k=>$v){
            $configs[] = Db::table('db_warehouse_config')->where('name',$v)->value('config_id');
        }
        $move = [];
        // 启动事务
        Db::startTrans();

        try {
            foreach ($params['info'] as $key => $value) {
                $move[$key]['move_id'] = 'M'.$user['tenant_id'].date('md').rand(100000,999999);
                if(!empty($value['tray_id']) && !empty($value['box_id']) && !empty($value['slice_id'])){
                    $move[$key]['tray_id'] = $value['tray_id'];
                    $move[$key]['box_id'] = $value['box_id'];
                    $move[$key]['slice_id'] = $value['slice_id'];
                    $move[$key]['config_id_one'] = $value['config_id'];
                    $move[$key]['goods_id'] = $value['goods_id'];
                    $move[$key]['goods_name'] = $value['goods_name'];
                    $move[$key]['config_id_two'] = $configs[$key];
                    $move[$key]['creator_id'] = $params['creator_id'];
                    $move[$key]['tenant_id'] = $params['tenant_id'];

                    $where3['tray_id'] = $value['tray_id'];
                    $where3['box_id'] = $value['box_id'];
                    $where3['slice_id'] = $value['slice_id'];
                    Db::table('db_slice')->where($where3)->update(['config_id' => $configs[$key]]);

                }elseif(!empty($value['tray_id']) && !empty($value['box_id']) && empty($value['slice_id'])){
                    $move[$key]['tray_id'] = $value['tray_id'];
                    $move[$key]['box_id'] = $value['box_id'];
                    $move[$key]['config_id_one'] = $value['config_id'];
                    $move[$key]['goods_id'] = $value['goods_id'];
                    $move[$key]['goods_name'] = $value['goods_name'];
                    $move[$key]['config_id_two'] = $configs[$key];
                    $move[$key]['creator_id'] = $params['creator_id'];
                    $move[$key]['tenant_id'] = $params['tenant_id'];

                    $where2['tray_id'] = $value['tray_id'];
                    $where2['box_id'] = $value['box_id'];
                    Db::table('db_box')->where($where2)->update(['config_id' => $configs[$key]]);

                }elseif(!empty($value['tray_id']) && empty($value['box_id']) && empty($value['slice_id'])){
                    $move[$key]['tray_id'] = $value['tray_id'];
                    $move[$key]['config_id_one'] = $value['config_id'];
                    $move[$key]['goods_id'] = $value['goods_id'];
                    $move[$key]['goods_name'] = $value['goods_name'];
                    $move[$key]['config_id_two'] = $configs[$key];
                    $move[$key]['creator_id'] = $params['creator_id'];
                    $move[$key]['tenant_id'] = $params['tenant_id'];

                    $where1['tray_id'] = $value['tray_id'];
                    Db::table('db_stock')->where($where1)->update(['config_id' => $configs[$key]]);
                }
            }
            $this->move->insertAllBy($move);
            // 提交事务
            Db::commit();
            return CatchResponse::success('', '新建成功');
        } catch (\Exception $exception) {

            Db::rollback();
            throw new Exception('失败');
        }



    }
    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function update(Request $request)
    {
        $params = $request->filterEmptyField()->param();
        $id = $params['id'];
        $this->move->updateBy($id, $params);
        return CatchResponse::success('', '编辑成功');
    }
    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function delete(Request $request)
    {
        $id = $request->post('id');
        $info=Db::table('db_move')->where('id',$id)->find();
        $mainInfo=Db::table('db_move_main')->where('move_code',$info['move_code'])->find();
        Db::startTrans();
        try {
            $number=$mainInfo['number']-1;
            if($number == $mainInfo['move_number'] && $mainInfo['move_number']>0){
                Db::table('db_move_main')->where('move_code',$info['move_code'])->update(['move_status'=>2]);
            }
            Db::table('db_move_main')->where('move_code',$info['move_code'])->update(['number'=>$number]);
            Db::table('db_move')->where('id',$id)->update(['deleted_at'=>time()]);
            Db::commit();
            return CatchResponse::success('', '删除成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('', '删除失败');
        }
//        $ids = Utils::stringToArrayBy($id);
//        foreach ($ids as $_id) {
//            $this->move->deleteBy($_id);
//        }
        //return CatchResponse::success('', '删除成功');
    }
    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function move(Request $request){
        $params = $request->param();
        $info = Db::table('db_move')->where('id',$params['id'])->find();
        $mainInfo = Db::table('db_move_main')->where('move_code',$info['move_code'])->find();
        Db::startTrans();
        try {
            $move_number=$mainInfo['move_number']+1;
            Db::table('db_stock')->where('tray_id',$info['tray_id'])->update(['config_id' => $info['config_id_two']]);
            Db::table('db_tray')->where('tray_id',$info['tray_id'])->update(['config_id' => $info['config_id_two']]);
            Db::table('db_move')->where('id',$params['id'])->update(['status'=>1]);
            Db::table('db_move_main')->where('move_code',$info['move_code'])->inc('move_number')->update();
            if($move_number == $mainInfo['number']){
                Db::table('db_move_main')->where('move_code',$info['move_code'])->update(['move_status'=>2]);
            }else{
                Db::table('db_move_main')->where('move_code',$info['move_code'])->update(['move_status'=>1]);
            }
            Db::commit();
            return CatchResponse::success('', '移库成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('', '移库失败');
        }
    }
    /**
     *
     * @throws \think\db\exception\DbException
     * @return \think\response\Json
     */
    public function moveAll(Request $request){
        $params = $request->param();
        $ids= explode(',',$params['ids']);
        $info = Db::table('db_move')->where('id',$ids[0])->find();
        $mainInfo = Db::table('db_move_main')->where('move_code',$info['move_code'])->find();
        $move_number = $mainInfo['move_number'];

        Db::startTrans();
        try {
            foreach ($ids as $k=>$v){
                $mation = Db::table('db_move')->where('id',$v)->find();

                //判断数据是否一致，是否已经移动过了
                $stock = Db::table('db_stock')->where('stock_id',$mation['stock_id'])->find();

                if($stock['config_id'] != $mation['config_id_one']){//说明这个库存已经被修改过
                    throw new Exception('失败，记录中已经包含已经移动的记录');
                }

                if($mation['status']==0){
                    $move_number++;

                    $warehouse_config_level3 = Db::table('db_warehouse_config')->field('id,parent_id')->where('config_id',$mation['config_id_two'])->find();
                    $warehouse_config_level2 = Db::table('db_warehouse_config')->where('id',$warehouse_config_level3['parent_id'])->find();
                    $warehouse_config_level1 = Db::table('db_warehouse_config')->field('config_id,name')->where('id',$warehouse_config_level2['parent_id'])->find();

                    Db::table('db_stock')->where('stock_id',$mation['stock_id'])
                        ->update([
                            'tray_id' => $mation['tray_id'],//更新托盘
                            'config_id' => $mation['config_id_two'],//更新库位
                            'entrepot_id'=>$warehouse_config_level1['config_id'],
                            'entrepot_name'=>$warehouse_config_level1['name']
                    ]);

                    //托盘表写入
                    $insertTrayData = [];
                    $insertTrayData['warehousing_id'] = $stock['warehousing_id'];
                    $insertTrayData['warehousing_son_id'] = $stock['warehousing_son_id'];
                    $insertTrayData['tray_id'] = $stock['tray_id'];
                    $insertTrayData['config_id'] = $mation['config_id_two'];
                    $insertTrayData['number'] = array_sum([$stock['Good_Qty'],$stock['Hold_Qty'],$stock['NG_Qty']]);
                    $insertTrayData['box_number'] =  ceil(($stock['number'] - $stock['out_number']) / $stock['packing_num']);
                    $insertTrayData['status'] = 1;
                    $insertTrayData['type'] = 2;//移库
                    $insertTrayData['move_id'] = $mation['move_id'];//移库明细编号

                    if(!empty($stock['Good_Qty'])){
                        $insertTrayData['goods_status'] = 'Good';
                    }elseif (!empty($stock['Hold_Qty'])){
                        $insertTrayData['goods_status'] = 'Hold';
                    }elseif (!empty($stock['NG_Qty'])){
                        $insertTrayData['goods_status'] = 'NG';
                    }

                    (new Tray)->insert($insertTrayData);

                    //Db::table('db_tray')->where('tray_id',$mation['tray_id'])->update(['config_id' => $mation['config_id_two']]);


                    Db::table('db_move')->where('id',$v)->update(['status'=>1]);
                    Db::table('db_move_main')->where('move_code',$mation['move_code'])->inc('move_number')->update();

                    //添加库存操作记录--start
                    $inventoryOperationRecordModel = new \catchAdmin\storehouse\model\InventoryOperationRecord();
                    $recordResult = (new InventoryOperationRecord($inventoryOperationRecordModel))->write(InventoryOperationRecord::ORDER_TYPE_YK,$mation['move_id'],[
                        'ext_json'=>json_encode($stock)
                    ]);
                    if(!$recordResult){
                        Db::rollback();
                        throw new Exception('[移库]库存操作记录创建失败');
                    }
                    //添加库存操作记录--end

                }
                if($move_number == $mainInfo['number']){
                    Db::table('db_move_main')->where('move_code',$mation['move_code'])->update(['move_status'=>2]);
                }else{
                    Db::table('db_move_main')->where('move_code',$mation['move_code'])->update(['move_status'=>1]);
                }
            }
            Db::commit();
            return CatchResponse::success('', '移库成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail($exception->getMessage());
        }
    }

    //拆箱拆件
    public function split(CatchAuth $auth,Request $request){
        $user = $auth->user();
        $stock_id = $request->post('stock_id');
        $num = $request->post('num');

        if(empty($num)){
            return CatchResponse::fail('拆箱/件数量错误');
        }

        if(empty($generate_ids =  array_unique($request->post('generate_ids')))){
            $generate_ids = [];
        }

        if(!empty($generate_ids) && count($generate_ids) != $num){
            return CatchResponse::fail('箱号数量不对，或者有重复的箱号');
        }

        $stock = Stock::where('stock_id',$stock_id)->find();

        if(empty($stock)){
            return CatchResponse::fail('库存ID错误');
        }

        if(!empty($stock->slice_id)){
            return CatchResponse::fail('片库存无法操作');
        }

        $record_id =  $user->tenant_id .  date("YmdHis") . mt_rand(10000,99999);
        $stock_result = Db::table('db_stock')->where('stock_id',$stock_id)->find();

        Db::startTrans();
        try {
            if(empty($stock->box_id) && empty($stock->slice_id)){//拆箱
                $result = (new Stock)->splitBox($stock_id,$num,$generate_ids);

                //添加库存操作记录--start
                $inventoryOperationRecordModel = new \catchAdmin\storehouse\model\InventoryOperationRecord();
                $recordResult = (new InventoryOperationRecord($inventoryOperationRecordModel))->write(InventoryOperationRecord::ORDER_TYPE_CX, "CX" . $record_id,[
                    'stock_id'=>$stock_id,
                    'box_number'=>$num,
                    'ext_json'=>json_encode($stock_result),
                    'tray_id'=>$stock_result['tray_id'],
                    'box_id'=>  implode(',',array_values(array_filter(array_column($result,'box_id'))))
                ]);
                if(!$recordResult){
                    Db::rollback();
                    throw new Exception('[拆箱]库存操作记录创建失败');
                }
                //添加库存操作记录--end
            }

            if(!empty($stock->box_id) && empty($stock->slice_id)) {//拆件
                $result = (new Stock)->splitSlice($stock_id,$num,$generate_ids);

                //添加库存操作记录--start
                $inventoryOperationRecordModel = new \catchAdmin\storehouse\model\InventoryOperationRecord();
                $recordResult = (new InventoryOperationRecord($inventoryOperationRecordModel))->write(InventoryOperationRecord::ORDER_TYPE_CJ, "CJ" . $record_id,[
                    'stock_id'=>$stock_id,
                    'number'=>$num,
                    'ext_json'=>json_encode($stock_result),
                    'tray_id'=>$stock_result['tray_id'],
                    'box_id'=>$stock_result['box_id'],
                    'slice_id'=>  implode(',',array_values(array_filter(array_column($result,'slice_id'))))
                ]);
                if(!$recordResult){
                    Db::rollback();
                    throw new Exception('[拆件]库存操作记录创建失败');
                }
                //添加库存操作记录--end
            }

            Db::commit();
            return CatchResponse::success($result, 'success');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail($exception->getMessage());
        }

    }

    //取消移库
    public function cancel(Request $request){
        $move_id = $request->post('move_id');

        $this->move->updateBy($move_id, ['status'=> -1 ]);
        return CatchResponse::success('', '取消成功');
    }
}